package com.Smart.smartscals.HttpTools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import com.Smart.smartscals.Entity.EntityDowload;
import com.Smart.smartscals.Entity.EntityParmToNet;
import com.Smart.smartscals.Utils.Tools;

import android.content.Context;
import android.util.Log;

/**
 * 下载工具类
 * 
 * 
 * huangbin
 */
public class DownLoadTools {

	private EntityDowload mEntityDowload;

	private String mfilePath;
	private StringBuilder mUrlDownLoad;
	private ArrayList<EntityParmToNet> arrEntityParmToNets;
	private String mFileName;
	private int mresponceMethodGetPost;
	private int mAPIType;
	private InputStream inputStream;
	private Context mContext;
	// 两种API的的不同响应；
	private HttpURLConnection mHttpURLConnection;
	private HttpResponse response;

	public DownLoadTools(EntityDowload entityDowload) {
		super();

		this.mEntityDowload = entityDowload;
		initParam();
	}

	/**
	 * 必须在线程中执行； ret:true才算成功；
	 */
	public boolean startTration() {

		return getExcluteHttp(mresponceMethodGetPost, mAPIType);
	}

	private void initParam() {
		// TODO 自动生成的方法存根
		this.mfilePath = mEntityDowload.getSavePath();
		this.mUrlDownLoad = new StringBuilder(mEntityDowload.getmDownLoadUrl());
		this.arrEntityParmToNets = mEntityDowload.getArrEntityParmToNets();
		this.mresponceMethodGetPost = mEntityDowload.getmRequestMethod();
		this.mAPIType = mEntityDowload.getmAPIType();
		this.mContext = mContext;
	}

	/**
	 * 
	 * @param methRequestMethod
	 * @param apiType
	 * @return
	 */
	private boolean getExcluteHttp(int methRequestMethod, int apiType) {
		boolean ret = false;
		try {
			if (apiType == 0) {
				// HttpUrlConnection
				if (getHttpConnnection(methRequestMethod) != null) {
					ret = true;
				}

			} else {
				// HttpClient
				ret = getHttpClient(mresponceMethodGetPost);

			}
		} catch (ClientProtocolException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}

		return ret;
	}

	/*
	 * 是否连接成功；
	 */
	private boolean getHttpClient(int methRequestMethod)
			throws ClientProtocolException, IOException {
		// TODO 自动生成的方法存根
		boolean ret = false;
		DefaultHttpClient client = new DefaultHttpClient();
		int code;
		if (methRequestMethod == 0) {// get

			HttpGet get = new HttpGet(setHttpUrlConnectionGetParam());
			response = client.execute(get);
			code = response.getStatusLine().getStatusCode();

		} else {// post

			UrlEncodedFormEntity encodedFormEntity = null;
			ArrayList<BasicNameValuePair> arrayListTmp = new ArrayList<BasicNameValuePair>();

			if (arrEntityParmToNets != null) {
				for (int i = 0; i < arrEntityParmToNets.size(); i++) {

					BasicNameValuePair basicNameValuePair = new BasicNameValuePair(
							arrEntityParmToNets.get(i).getmToNetKey(),
							arrEntityParmToNets.get(i).getmToNetName());
					arrayListTmp.add(basicNameValuePair);
				}
				encodedFormEntity = new UrlEncodedFormEntity(arrayListTmp);
			}
			HttpPost post = new HttpPost(mUrlDownLoad.toString());

			if (encodedFormEntity != null)
				post.setEntity(encodedFormEntity);

			response = client.execute(post);
			code = response.getStatusLine().getStatusCode();

		}
		
		
		if (code == 200) {
			inputStream = response.getEntity().getContent();
			ret = true;
		}
		return ret;

	}

	/**
	 * 获取UrlConnection实体； 没有获取成功返回Null；
	 * 
	 * @param methRequestMethod
	 * 
	 * @return
	 * @throws IOException
	 */
	private InputStream getHttpConnnection(int methRequestMethod)
			throws IOException {
		if (!HttpTools.isNetWork(mContext))
			return null;

		if (methRequestMethod == 0) {// get
			URL url = new URL(setHttpUrlConnectionGetParam());
			Log.v("msg", "--->stat:" + setHttpUrlConnectionGetParam());
			mHttpURLConnection = (HttpURLConnection) url.openConnection();
			mHttpURLConnection.connect();

		} else {// post
			URL url = new URL(mUrlDownLoad.toString());

			// 使用HttpURLConnection打开连接
			mHttpURLConnection = (HttpURLConnection) url.openConnection();
			// 因为这个是post请求,设立需要设置为true
			mHttpURLConnection.setDoOutput(true);
			mHttpURLConnection.setDoInput(true);
			// 设置以POST方式
			mHttpURLConnection.setRequestMethod("POST");
			// Post 请求不能使用缓存
			mHttpURLConnection.setUseCaches(false);
			mHttpURLConnection.setInstanceFollowRedirects(true);
			// 配置本次连接的Content-type，配置为application/x-www-form-urlencoded的
			mHttpURLConnection.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			// 连接，从postUrl.openConnection()至此的配置必须要在connect之前完成，
			// 要注意的是connection.getOutputStream会隐含的进行connect。
			mHttpURLConnection.connect();
			// 设置参数；
			setHttpUrlConnectionPostParam();

		}
		Tools.setLog("---->state:" + mHttpURLConnection.getResponseCode());

		if (mHttpURLConnection.getResponseCode() != 200) {
			return null;
		}
		inputStream = mHttpURLConnection.getInputStream();
		return inputStream;

	}

	private void setHttpUrlConnectionPostParam() throws IOException {
		// TODO 自动生成的方法存根
		if (!setHttpUrlConnectionGetParam().equals(mUrlDownLoad)) {
			byte[] bypes = setHttpUrlConnectionGetParam().toString().getBytes();
			mHttpURLConnection.getOutputStream().write(bypes);// 输入参数
		}

	}

	/**
	 * 生成HttpUrlConnectionGet提交参数的方法；
	 * 
	 * @return
	 */
	private String setHttpUrlConnectionGetParam() {
		// TODO 自动生成的方法存根
		if (arrEntityParmToNets == null || arrEntityParmToNets.size() == 0) {
			return mUrlDownLoad.toString();
		} else {
			if (mUrlDownLoad.toString().contains("?")) {
				mUrlDownLoad.append("?");
			}
			for (int i = 0; i < arrEntityParmToNets.size(); i++) {

				mUrlDownLoad.append("&");
				mUrlDownLoad.append(arrEntityParmToNets.get(i).getmToNetKey());
				mUrlDownLoad.append("=");
				mUrlDownLoad.append(arrEntityParmToNets.get(i).getmToNetName());
			}
			return mUrlDownLoad.toString();

		}

	}

	/**
	 * 获取文件的长度，单位是Bytes；
	 * 
	 * @return
	 */
	public long getSizeOfFile() {
		if (mAPIType == 0)
			return mHttpURLConnection.getContentLength();
		else
			return response.getEntity().getContentLength();
	}

	/**
	 * 获取网络文本(比如Jason数据,xml数据)；
	 * 
	 * @return
	 */
	public String getStrFromNet() {

		StringBuilder tmpLine = new StringBuilder();
		String tmp;

		InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

		try {
			while ((tmp = bufferedReader.readLine()) != null) {
				tmpLine = tmpLine.append(tmp);
			}
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}

		return tmpLine.toString();

	}

	/**
	 * 获取文件的名字
	 * 
	 * @param url
	 *            要下载的Url
	 * @return
	 */
	public String getFileName(String url) {
		String filename = "";
		boolean isok = false;

		try {
			URL urlTmp = new URL(setHttpUrlConnectionGetParam());
			Log.v("msg", "--->stat:" + setHttpUrlConnectionGetParam());
			mHttpURLConnection = (HttpURLConnection) urlTmp.openConnection();
			mHttpURLConnection.connect();
			// 从UrlConnection中获取文件名称

			Map<String, List<String>> hf = mHttpURLConnection.getHeaderFields();

			if (hf == null) {
				return null;
			}
			Set<String> key = hf.keySet();
			if (key == null) {
				return null;
			}

			for (String skey : key) {
				List<String> values = hf.get(skey);
				for (String value : values) {
					String result;
					try {
						result = new String(value.getBytes("ISO-8859-1"), "GBK");
						int location = result.indexOf("filename");
						if (location >= 0) {
							result = result.substring(location
									+ "filename".length());
							filename = result
									.substring(result.indexOf("=") + 1);
							isok = true;
						}
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}// ISO-8859-1 UTF-8 gb2312
				}
				if (isok) {
					break;
				}
			}

			// 从路径中获取
			if (filename == null || "".equals(filename)) {
				filename = url.substring(url.lastIndexOf("/") + 1);
			}
		} catch (MalformedURLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return filename;
	}

	/**
	 * 需要下载到SD卡中否（会创建目录，和文件）
	 * 
	 * @param downLoadSize
	 * @throws IOException
	 */
	public void saveInSdCard(DownLoadSize downLoadSize) throws IOException {

		if (Tools.isSdCardVisable()) {// 判断网络是否可用
			if (getSizeOfFile() < Tools.getSDOfferSize()) {// 表明存储空间足够下载本文件，开始下载文件
				StringBuilder builder = new StringBuilder();// 用于存储路径

				builder.append(Tools.getSdAbsolutePath() + mfilePath);
				File mFileDir = new File(builder.toString());
				if (!mFileDir.exists()) {// 创建下载目录
					mFileDir.mkdir();
				}
				// 要下载的文件；
				File mFile = new File(builder.append(
						getFileName(mUrlDownLoad.toString())).toString());
				// 創建要下载的文件;
				mFile.createNewFile();
				InputStreamReader in = new InputStreamReader(inputStream);
				FileOutputStream fileOutputStream = new FileOutputStream(mFile);
				byte[] buf = new byte[1024];
				// 寫入实体文件；
				int len;
				while ((len = inputStream.read(buf)) != -1) {
					// 保存的时候，记住每次读的长度不一定是1024的整数倍；
					fileOutputStream.write(buf, 0, len);
					downLoadSize.getDownLoadingSize(len);
				}
				// 关闭流操作
				fileOutputStream.flush();
				inputStream.close();
				fileOutputStream.close();

			}

		}

	}

	/**
	 * 返回当前下载的大小；
	 * 
	 * @author hb
	 * 
	 */
	public abstract class DownLoadSize {
		abstract void getDownLoadingSize(int size);
	}
}
